package twoD.IsoPfem;

import inf.v3d.view.Viewer;
import twoD.IsoPfem.math.FunctionRToR;
import twoD.IsoPfem.math.Interval;

public class SimpleBeamDemo2 {
	public static void main(String[] args) {
		ElasticStructure struct = new SimpleBeamDemo2().createModel();

		struct.solveLinearStaticEquilibrium();
		struct.listingDisplacements();

		Viewer view = new Viewer();
		Visualizer viz = new Visualizer(struct, view);
		double d_max = viz.automaticScale();
		viz.drawConstraints();
		viz.drawForces();
		viz.drawEdgeLoads();
		viz.drawElements();

		viz.postAutomaticScale(d_max);
		viz.drawDisplacedStructure();
		// viz.drawSigma11();

		view.setVisible(true);
	}

	public ElasticStructure createModel() {

		Mesh M = new Mesh();

		// nodes
		Node n0 = M.addNode(new Node(0, 0));
		Node n1 = M.addNode(new Node(1, 0));
		Node n2 = M.addNode(new Node(1, 1));
		Node n3 = M.addNode(new Node(0, 1));

		// edges
		IEdge e0 = M.addEdge(new StraightEdge(n0, n1));
		IEdge e1 = M.addEdge(new StraightEdge(n1, n2));
		IEdge e2 = M.addEdge(new StraightEdge(n0, n2));
		IEdge e3 = M.addEdge(new StraightEdge(n2, n3));
		IEdge e4 = M.addEdge(new StraightEdge(n3, n0));

		IFace f0 = M
				.addFace(new FlatFace(new Node[] { n0, n1, n2 }, e0, e1, e2));
		IFace f1 = M
				.addFace(new FlatFace(new Node[] { n0, n2, n3 }, e3, e4, e2));

		Triangle t0 = new Triangle(f0);
		Triangle t1 = new Triangle(f1);
		M.addGeometry(t0);
		M.addGeometry(t1);

		ElasticStructure struct = new ElasticStructure(M);
		RealTable realTable = new RealTable(1, 0.2);
		realTable.setThickness(1.0 / 20);

		// elements
		struct.addElement(new CST2(realTable, t0));
		IElement el1 = struct.addElement(new CST2(realTable, t1));

		// constraints
		Constraint c1 = new Constraint(false, false);
		n0.setConstraint(c1);
		n3.setConstraint(c1);
		e4.setConstraint(c1);

		// Force f = new Force(1, 0);
		// n1.setForce(f);
		// n2.setForce(f);

		EdgeLoad eload = new EdgeLoad(e1, new FunctionRToR() {

			@Override
			public double valueAt(double x) {
				return -2;
			}

			@Override
			public int getP() {
				return 0;
			}

			@Override
			public Interval getDomain() {
				return new Interval(0, 1);
			}

			@Override
			public double[] getBreakpoints() {
				return null;
			}

			@Override
			public double derivativeAt(double x) {
				return 0;
			}
		});

		el1.addEdgeLoad(eload);

		return struct;
	}
}
